# coding:utf-8
# writingtime: 2022-6-30
# author: wanjun
import os
import datetime
from Utilities.AutoGetOperator.selectionMethod.selectPackage import get_func
from Utilities.ConstructData.DistributionFunctionData import Distribute
from Utilities.Plot.SimplePlot import SimpleClass
from Operators.OperationOperators.Algebraic import A,GA,WA
from Operators.OperationOperators.AcezelAlsina import AcezelAlsinaWA
from Operators.OperationOperators.Dombi import DombiWA
from Operators.OperationOperators.Frank import FrankWA
from Operators.OperationOperators.Hamacher import HamacherWA



root_path = os.path.realpath(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))

getSatisfactionWeight=get_func(root_path+r"\DecisionSystem\Utilities\GetWeight\getExpertWeight\GetSatisfactionWeight.py",'getSatisfactionWeight')
MABAC=get_func(root_path+r'\DecisionSystem\DecisionMethod\MABAC.py','MABAC')
getS=get_func(root_path+r'\DecisionSystem\ScoreFunction\getS.py','getS')

class Ops_Analyze:
    def __init__(self,list_operator=[],data_group=[],
                 getExpertWeight=getSatisfactionWeight,getAttributeWeight=MABAC,scoreFunction=getS,
                 q=3,x=2,a=2,b=2,*wast1,**waste2):
        '''
        function:测试多个算子对数据的聚合结果分析
        :param list_operator: 算子函数列表
        :param data_group: 数据群
        :param getExpertWeight: 专家权重计算方式
        :param getAttributeWeight: 属性权重计算方式
        :param scoreFunction: 得分函数
        :param q: q
        :param x: 一个参数时用x
        :param a: 两个参数时用a，b
        :param b: 两个参数用a，b
        '''
        # 对于比较算子的初始化
        self.list_operator=[]
        if len(list_operator)<2:
            foundation_op=[AcezelAlsinaWA,DombiWA,FrankWA]+list_operator
            self.list_operator=foundation_op
        else:
            self.list_operator=list_operator
        # 对于数据群的初始化
        if len(data_group):
            self.data_group=data_group
        else:
            self.data_group=Distribute().get_Gaussian_random(get_return=True)
        # 对于计算专家权重方式的初始化
        self.getExpertWeight=getExpertWeight
        # 对于计算属性权重方式的初始化
        self.getAttributeWeight=getAttributeWeight
        # 对于得分函数的初始化
        self.getScore=scoreFunction
        # 专家权重
        self.expert_weight = self.getExpertWeight(self.data_group)
        # 属性权重
        self.attribute_weight = []
        self.q = q
        self.x = x
        self.a = a
        self.b = b

    def set_dataGroup(self,data_group):
        '''
        function: 设置决策数据群
        :param data_group: 决策群
        :return:
        '''
        # self.data_group=data_group

        self.data_group =data_group
    def setExpertWeight(self,expert_weight):
        '''
        function: 设置专家权重
        :param weight_weight:专家权重
        :return:
        '''
        self.expert_weight=expert_weight

    def setAttributeWeight(self,attribute_weight):
        '''
        function: 设置属性权重
        :param attribute_weight: 属性权重
        :return:
        '''
        self.attribute_weight=attribute_weight

    def set_q(self,q):
        '''
        function: 对q的值进行修改
        :param q:
        :return:
        '''
        self.q=q

    def set_x(self,x):
        '''
        function: 对x的值进行修改
        :param x:
        :return:
        '''
        self.x=x

    def set_a(self,a):
        '''
        function: 对a的值进行修改
        :param a:
        :return:
        '''
        self.a=a

    def set_b(self,b):
        '''
        function: 对b的值进行修改
        :param b:
        :return:
        '''
        self.b=b

    def matrixReverse(self,matrix):
        '''
        function: 功能函数
        :param matrix: 矩阵
        :return: 行列交换的矩阵
        '''
        newMatrix = []
        for x in range(len(matrix[0])):
            temp = []
            for y in range(len(matrix)):
                temp.append(matrix[y][x])
            newMatrix.append(temp)

        return newMatrix

    def arrge(self,operator,expertWeight=[],attr_weight=[]):
        '''
        function: 对决策群进行集结
        :return:
        '''
        # 设置q的值
        # 对于设置专家权重的判断
        if len(expertWeight):
            pass
        else:
            self.setExpertWeight(expertWeight)

        aggre_matrix_1 = []  # 存放运算结果
        '''集结矩阵'''
        for i in range(len(self.data_group[0])):
            li_1 = []
            for j in range(len(self.data_group[0][0])):
                li_1.append(
                    operator([self.data_group[k][i][j] for k in range(len(self.data_group))], self.expert_weight,
                             self.q).getResult())
            aggre_matrix_1.append(li_1)
        if len(attr_weight):
            attr_weight = attr_weight
    
        else:
            # 属性权重,对于属性进行分析，因此需要翻转
            attr_weight = self.getAttributeWeight(self.matrixReverse(aggre_matrix_1),
                                                  [1 / len(aggre_matrix_1) for i in range(len(aggre_matrix_1))],
                                                  self.q).getResult()
        # 最终结果
        fianl_vlaue = [operator(i, attr_weight, self.q).getResult() for i in aggre_matrix_1]

        return fianl_vlaue

    def saveData(self,fname='1.txt',data_group=[],expertWeight=[],atttributeWeight=[],q_range=[]):
        '''
        function: 存储数据
        :param data_group: 决策群
        :param expertWeight: 专家权重
        :param atttributeWeight: 属性权重
        :param q:
        :return:
        '''

        # 写入data数据
        try:
            data_file = open(fname, "w")
            data_file.write("q:\n" + str(q_range) + "\n" +
                            "data set:\n" + str(data_group) + "\n" +
                            "expert weight:\n" + str(expertWeight) + "\n"
                            "attribute weight:\n" + str(atttributeWeight) + "\n")
            print(fname + " is saved")
            data_file.close()
        except:
            print(fname + " fail")
        # 存储数据

    def OpsAnalyze(self):
        '''
        function: 对于多个算子对比分析
        :return:
        '''
        # 创建文件夹
        root_path = os.path.realpath(os.path.dirname(os.path.dirname(__file__)))
        path = os.path.join(root_path, r'Data\randonData\OperatorsComparision\get_Gaussian_random')
        path = os.path.join(path, datetime.datetime.now().strftime('%Y-%m-%d'))
        fpath = os.path.join(path, r'img')
        tpath = os.path.join(path, r'data')
        try:
            os.makedirs(fpath)  # 图片存储地址
            os.makedirs(tpath)  # 数据存储地址
        except:
            print('folder already exists')



        q_range=12
        length=len(self.list_operator)
        data_group=[]
        name_list=[]
        # print(self.list_operator,len(self.list_operator))
        for i in range(length):
            temp_list=[]
            for j in range(3,q_range):
                self.set_q(j)
                temp=self.arrge(self.list_operator[i])
                temp_list.append([self.getScore(temp[k],self.q).getScore() for k in range(len(temp))])
            data_group.append(self.matrixReverse(temp_list))
            name_list.append(self.list_operator[i].__name__)
        tname = os.path.join(tpath,'result.txt')
        self.saveData(tname,self.data_group,self.expert_weight,self.attribute_weight,[3+i for i in range(q_range-3)])
        SimpleClass().OpSensitivity(data_group,[3+i for i in range(q_range-3)],name_list,
                                    filename=fpath,imgSaving=True,imgShow=False)



if __name__=='__main__':
    data_group = [[[([0.44102, 0.54102], [0.45898, 0.55898]), ([0.40009, 0.50009], [0.49991, 0.59991]), ([0.011, 0.10111], [0.89889, 0.989]), ([0.12836, 0.24255], [0.75745, 0.87164]), ([0.31595, 0.4273], [0.5727, 0.68405])], [([0.35291, 0.45291], [0.54709, 0.64709]), ([0.56412, 0.67117], [0.32883, 0.43588]), ([0.69203, 0.82802], [0.17198, 0.30797]), ([0.24712, 0.38141], [0.61859, 0.75288]), ([0.79534, 0.89689], [0.10311, 0.20466])], [([0.504, 0.604], [0.396, 0.496]), ([0.65123, 0.80082], [0.19918, 0.34877]), ([0.011, 0.10111], [0.89889, 0.989]), ([0.24724, 0.3815], [0.6185, 0.75276]), ([0.1974, 0.34609], [0.65391, 0.8026])], [([0.20075, 0.3505], [0.6495, 0.79925]), ([0.81664, 0.90832], [0.09168, 0.18336]), ([0.16088, 0.29132], [0.70868, 0.83912]), ([0.45858, 0.55858], [0.44142, 0.54142]), ([0.52117, 0.62117], [0.37883, 0.47883])], [([0.46979, 0.56979], [0.43021, 0.53021]), ([0.56974, 0.67961], [0.32039, 0.43026]), ([0.06317, 0.15908], [0.84092, 0.93683]), ([0.30252, 0.41835], [0.58165, 0.69748]), ([0.08655, 0.18506], [0.81494, 0.91345])]], [[([0.49528, 0.59528], [0.40472, 0.50472]), ([0.49633, 0.59633], [0.40367, 0.50367]), ([0.77554, 0.88369], [0.11631, 0.22446]), ([0.77864, 0.88576], [0.11424, 0.22136]), ([0.42246, 0.52246], [0.47754, 0.57754])], [([0.52419, 0.62419], [0.37581, 0.47581]), ([0.39392, 0.49392], [0.50608, 0.60608]), ([0.011, 0.10111], [0.89889, 0.989]), ([0.79627, 0.89751], [0.10249, 0.20373]), ([0.08159, 0.17954], [0.82046, 0.91841])], [([0.80593, 0.90297], [0.09703, 0.19407]), ([0.011, 0.10111], [0.89889, 0.989]), ([0.35335, 0.45335], [0.54665, 0.64665]), ([0.12092, 0.23138], [0.76862, 0.87908]), ([0.11198, 0.21798], [0.78202, 0.88802])], [([0.05787, 0.15319], [0.84681, 0.94213]), ([0.25118, 0.38412], [0.61588, 0.74882]), ([0.65022, 0.80015], [0.19985, 0.34978]), ([0.57334, 0.68501], [0.31499, 0.42666]), ([0.68134, 0.82089], [0.17911, 0.31866])], [([0.95, 0.99], [0.01, 0.05]), ([0.12042, 0.23062], [0.76938, 0.87958]), ([0.011, 0.10111], [0.89889, 0.989]), ([0.51414, 0.61414], [0.38586, 0.48586]), ([0.94752, 0.98801], [0.01199, 0.05248])]], [[([0.45119, 0.55119], [0.44881, 0.54881]), ([0.48575, 0.58575], [0.41425, 0.51425]), ([0.47072, 0.57072], [0.42928, 0.52928]), ([0.011, 0.10111], [0.89889, 0.989]), ([0.1815, 0.32225], [0.67775, 0.8185])], [([0.2023, 0.35153], [0.64847, 0.7977]), ([0.19708, 0.34561], [0.65439, 0.80292]), ([0.72007, 0.84671], [0.15329, 0.27993]), ([0.81522, 0.90761], [0.09239, 0.18478]), ([0.40491, 0.50491], [0.49509, 0.59509])], [([0.93064, 0.97451], [0.02549, 0.06936]), ([0.45161, 0.55161], [0.44839, 0.54839]), ([0.58145, 0.69717], [0.30283, 0.41855]), ([0.55485, 0.65728], [0.34272, 0.44515]), ([0.67083, 0.81389], [0.18611, 0.32917])], [([0.75188, 0.86792], [0.13208, 0.24812]), ([0.1784, 0.3176], [0.6824, 0.8216]), ([0.03856, 0.13173], [0.86827, 0.96144]), ([0.0279, 0.11989], [0.88011, 0.9721]), ([0.75776, 0.87184], [0.12816, 0.24224])], [([0.6708, 0.81387], [0.18613, 0.3292]), ([0.15574, 0.28362], [0.71638, 0.84426]), ([0.42732, 0.52732], [0.47268, 0.57268]), ([0.55275, 0.65412], [0.34588, 0.44725]), ([0.48852, 0.58852], [0.41148, 0.51148])]], [[([0.02382, 0.11535], [0.88465, 0.97618]), ([0.1605, 0.29074], [0.70926, 0.8395]), ([0.56105, 0.66658], [0.33342, 0.43895]), ([0.46258, 0.56258], [0.43742, 0.53742]), ([0.38775, 0.48775], [0.51225, 0.61225])], [([0.83268, 0.91634], [0.08366, 0.16732]), ([0.90002, 0.95002], [0.04998, 0.09998]), ([0.35479, 0.45479], [0.54521, 0.64521]), ([0.38058, 0.48058], [0.51942, 0.61942]), ([0.67814, 0.81876], [0.18124, 0.32186])], [([0.30762, 0.42175], [0.57825, 0.69238]), ([0.011, 0.10111], [0.89889, 0.989]), ([0.13874, 0.25812], [0.74188, 0.86126]), ([0.08554, 0.18393], [0.81607, 0.91446]), ([0.42256, 0.52256], [0.47744, 0.57744])], [([0.44025, 0.54025], [0.45975, 0.55975]), ([0.39879, 0.49879], [0.50121, 0.60121]), ([0.27837, 0.40224], [0.59776, 0.72163]), ([0.12169, 0.23254], [0.76746, 0.87831]), ([0.07525, 0.1725], [0.8275, 0.92475])], [([0.14842, 0.27262], [0.72738, 0.85158]), ([0.36494, 0.46494], [0.53506, 0.63506]), ([0.15367, 0.2805], [0.7195, 0.84633]), ([0.59886, 0.72329], [0.27671, 0.40114]), ([0.41428, 0.51428], [0.48572, 0.58572])]], [[([0.07939, 0.1771], [0.8229, 0.92061]), ([0.01547, 0.10608], [0.89392, 0.98453]), ([0.07441, 0.17156], [0.82844, 0.92559]), ([0.40025, 0.50025], [0.49975, 0.59975]), ([0.56141, 0.66711], [0.33289, 0.43859])], [([0.57442, 0.68664], [0.31336, 0.42558]), ([0.33108, 0.43739], [0.56261, 0.66892]), ([0.35195, 0.45195], [0.54805, 0.64805]), ([0.37909, 0.47909], [0.52091, 0.62091]), ([0.03026, 0.12251], [0.87749, 0.96974])], [([0.64062, 0.78593], [0.21407, 0.35938]), ([0.36434, 0.46434], [0.53566, 0.63566]), ([0.44708, 0.54708], [0.45292, 0.55292]), ([0.81091, 0.90546], [0.09454, 0.18909]), ([0.41886, 0.51886], [0.48114, 0.58114])], [([0.51795, 0.61795], [0.38205, 0.48205]), ([0.4833, 0.5833], [0.4167, 0.5167]), ([0.59114, 0.71172], [0.28828, 0.40886]), ([0.73736, 0.85824], [0.14176, 0.26264]), ([0.6707, 0.8138], [0.1862, 0.3293])], [([0.011, 0.10111], [0.89889, 0.989]), ([0.55878, 0.66318], [0.33682, 0.44122]), ([0.01424, 0.10471], [0.89529, 0.98576]), ([0.90811, 0.95649], [0.04351, 0.09189]), ([0.32666, 0.43444], [0.56556, 0.67334])]]]


    op=get_func(root_path+r'\DecisionSystem\Operators\FunctionOperators\BonferroniMean.py',"SchweizerSklarBonferroniMeanWA")
    op1=get_func(root_path+r'\DecisionSystem\Operators\FunctionOperators\BonferroniMean.py',"BonferroniMeanWA")
    (Ops_Analyze([op]).OpsAnalyze())
